#include <pnm.h>
#include <stdio.h>
#include <stdlib.h>

void annToCoord( pnm ann, int * I, int * J ){

  int width = pnm_get_width(ann);
  int height = pnm_get_height(ann);

  int i, j;

  for( i = 0; i < height; i++ ){
    for( j = 0; j < width; j++ ){
      int indice = 0;
      indice = (pnm_get_component( ann, i, j, 1) & 15) << 8;
      indice = indice + pnm_get_component( ann, i, j, 0);
      J[ i * width + j ] = indice;
      indice = 0;
      indice = (pnm_get_component( ann, i, j, 2)) << 4;
      indice = indice + (pnm_get_component( ann, i, j, 1) >> 4);
      I[ i * width + j ] = indice;
    }
  }
}

void run(pnm imb, pnm ann, pnm ima){

  int i, j;

  int width = pnm_get_width(ann);
  int height = pnm_get_height(ann);

  int wb = pnm_get_width(imb);
  int hb = pnm_get_height(imb);

  unsigned int * somme_a = malloc( width * height * sizeof(unsigned int) * 3);

  for( i = 0; i < height * width * 3; i++ ){
    somme_a[ i ] = 0;
  }

  int * nb_somme_a = malloc( width * height * sizeof(int) );

  for( i = 0; i < width * height; i++){
    nb_somme_a[ i ] = 0;
  }

  int * I = malloc( width * height * sizeof(int) );
  int * J = malloc( width * height * sizeof(int) );

  annToCoord( ann, I, J);

  int ai = 0;
  int aj = 0;

  int ib = 0;
  int jb = 0;

  for( i = 0; i < height; i++ ){
    for( j = 0; j < width; j++ ){

      ib = I[ i * width + j ];
      jb = J[ i * width + j ];

      for( ai = 0; ai < 7; ai++){
        for( aj = 0; aj < 7; aj++){
          
          if( ib + ai >= 0 && ib + ai < hb){
            if( jb + aj >= 0 && jb + aj < wb){
              if( i + ai >= 0 && i + ai < height){
                if( j + aj >=0 && j + aj < width){
                  somme_a[ 3 * ((i + ai) * width + (j + aj)) + 0 ] += pnm_get_component( imb, (ib + ai), (jb + aj), 0); 
                  somme_a[ 3 * ((i + ai) * width + (j + aj)) + 1 ] += pnm_get_component( imb, (ib + ai), (jb + aj), 1); 
                  somme_a[ 3 * ((i + ai) * width + (j + aj)) + 2 ] += pnm_get_component( imb, (ib + ai), (jb + aj), 2); 
           
                  nb_somme_a[ (i + ai) * width + (j + aj) ] += 1;
                }
              }
            }
          }

        }
      }

    }
  }

  for( i = 0; i < height; i++ ){
    for( j = 0; j < width; j++ ){
      pnm_set_component(ima, i, j, 0, (unsigned short) (somme_a[ 3 * (i * width + j) + 0] *1.0 / nb_somme_a[ i * width + j] ) );
      pnm_set_component(ima, i, j, 1, (unsigned short) (somme_a[ 3 * (i * width + j) + 1] *1.0 / nb_somme_a[ i * width + j] ) );
      pnm_set_component(ima, i, j, 2, (unsigned short) (somme_a[ 3 * (i * width + j) + 2] *1.0 / nb_somme_a[ i * width + j] ) );
    }
  }

  free(somme_a);
  free(nb_somme_a);
  free(I);
  free(J);
}

void 
usage (char *s){
  fprintf(stderr, "Usage: %s <b> <a-ann> <a>\n", s);
  exit(EXIT_FAILURE);
}

int main(int argc, char * argv[]){

	if (argc != 4) usage(argv[0]);
	pnm imb = pnm_load(argv[1]);
	pnm ann = pnm_load(argv[2]);
	pnm ima = pnm_load(argv[3]);
	run(imb, ann, ima);
	pnm_save(ima, PnmRawPpm, argv[3]);
	pnm_free(ima);
	pnm_free(imb);
	pnm_free(ann);
	return 0;
}